package com.example.myandroidapp.kotlin

import android.util.JsonWriter
import org.json.JSONObject
import org.json.JSONStringer

/*
* 在 Kotlin 中，let、with、run 和 apply 都是作用域函数（scope functions），它们的主要区别在于 上下文对象的访问方式 和 返回值类型。以下是它们的核心区别对比：
函数	  上下文对象引用	   返回值	 是否扩展函数	   空安全支持	      典型使用场景
let	   it	           Lambda 结果	✅	       ✅ (?.)	       空安全检查、数据转换
with	this	       Lambda 结果	❌ (参数)	❌	           对象初始化和操作
run	   this	          Lambda 结果	✅	        ✅ (?.)	       对象配置+计算结果、替代构造器
apply	this	      对象本身	    ✅	        ❌	           对象初始化、Builder 模式
*/
fun main() {
    let_test()
    with_test()
    apply_test()
    run_test()
}

//let 函数：name不为空才执行 let中方法
//使用方式：name?.let {}
fun let_test() {
//    val name: String? = null
    val name: String? = "hsh"

    name?.let {
        println("Name length: ${it.length}") // 仅当 name 非空时执行
        it.uppercase() // 返回值
    } // 返回 null（因为 name 为 null）

// 等效的非空检查：
    if (name != null) {
        println(name.length)
    }
}


// 定义一个简单的汽车类
class Car {
    var isEngineRunning = false
    var isACOn = false
    var currentMusic = ""
    var navigationDestination = ""
    var speed = 0
}

//with 函数：对象上下文操作
//使用方式：with(对象) {}
fun with_test() {
    val car = Car()
    //传统写法
    /*car.startEngine()
    car.turnOnAC()
    car.playMusic("Jazz")
    car.setNavigation("Home")*/
    with(car) {
        isEngineRunning = true
        isACOn = true
        currentMusic = "Playing music"
    }
    println(car.currentMusic + car.isACOn + car.isEngineRunning)
}

/*
* apply 函数：对象上下文操作
* 使用方式：对象.apply {}
*
*/
fun apply_test() {
    val car = Car()
    car.apply {
        navigationDestination = "Home"
        speed = 10
    }
    println(car.navigationDestination + car.speed)
}

/*
* run 函数：对象上下文操作
* 使用方式：对象.run {}
*
*/
fun run_test() {
    val car = Car()
    val result = car.run {
        navigationDestination = "Homerun"
        speed = 100
        "导航目的地：${navigationDestination}，速度：${speed}"
    }
    println(result)

    //单用run作用域
    // 1. 简化多步计算
    val area = run {
        val width = 10
        val height = 5
        width * height // 返回面积
    }
    println("矩形面积: $area") // 输出: 矩形面积: 50
}